package org.whatever.aha.zjut.platform.service.competition;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.whatever.aha.zjut.base.constant.ErrorCode;
import org.whatever.aha.zjut.base.constant.StatusConstant;
import org.whatever.aha.zjut.base.exception.AppException;
import org.whatever.aha.zjut.platform.dto.competition.*;
import org.whatever.aha.zjut.platform.entity.competition.Competition;
import org.whatever.aha.zjut.platform.entity.competition.CompetitionStage;
import org.whatever.aha.zjut.platform.entity.competition.CompetitionStageStatus;
import org.whatever.aha.zjut.platform.entity.project.ProjectTeacher;
import org.whatever.aha.zjut.platform.mapper.competition.CompetitionMapper;
import org.whatever.aha.zjut.platform.service.StudentInfoService;
import org.whatever.aha.zjut.platform.service.project.*;
import org.whatever.aha.zjut.platform.service.school.JudgeProjectDistributionService;
import org.whatever.aha.zjut.platform.service.school.ProjectScoreService;
import org.whatever.aha.zjut.platform.util.CheckUtil;
import org.whatever.aha.zjut.platform.util.StatusConvertUtil;
import org.whatever.aha.zjut.platform.vo.competition.*;
import org.whatever.aha.zjut.platform.vo.project.ProjectDetailVo;
import org.whatever.aha.zjut.platform.vo.school.SchoolRecInfoVo;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Vc
 * @version 1.0
 * @Desc
 * @date 2021/08/14 11:10
 */
@Service
@RequiredArgsConstructor
public class CompetitionService {
    final CompetitionMapper competitionMapper;
    final CompetitionKeyPointService competitionKeyPointService;
    final CompetitionTrackService competitionTrackService;
    final CompetitionStageService competitionStageService;
    final CompetitionStageAwardService competitionStageAwardService;
    final CompetitionStageStatusService competitionStageStatusService;
    final AcademyCompetitionService academyCompetitionService;
    @Autowired
    private JudgeProjectDistributionService judgeProjectDistributionService;
    @Autowired
    private ProjectService projectService;
    final ProjectMemberService projectMemberService;
    final StudentInfoService studentInfoService;

    final ProjectScoreService projectScoreService;
    final ProjectReturnLogService projectReturnLogService;
    final ProjectTeacherService projectTeacherService;
    final ProjectMemberApplyService projectMemberApplyService;

    /**
     * 根据时间节点确定当前stage及stageStatus信息
     *
     * @param compId
     * @return
     */
    public Map<String, Object> getStageInfoByTime(int compId) {
        if(competitionMapper.selectCount(new QueryWrapper<Competition>().eq("comp_id",compId))<1){
            throw new AppException(ErrorCode.COMPETITION_LACK);
        }
        Map<String, Object> map = new HashMap<>();
        List<CompetitionStage> stages = competitionStageService.getStageByCompId(compId);
        for(CompetitionStage stage : stages){
            List<CompetitionStageStatus> compStageStatusList = competitionStageStatusService.getCompStageStatus(stage.getStageId());
            Date date = new Date();
            for (CompetitionStageStatus competitionStageStatus : compStageStatusList) {
                if (CheckUtil.checkStageStatusByTime(stage, competitionStageStatus, date, stages.size())){
                    //提交开始前为提交状态,在开始和结束时间内为该状态,当前时间晚于公示结束时间，为公示阶段
                    map.put("competitionStageStatus", competitionStageStatus);
                    map.put("competitionStage", stage);
                    List<CompetitionKeyPointVo> compKeyPointVo = competitionKeyPointService.getCompKeyPointVo(compId, competitionStageStatus.getStageId());
                    map.put("compKeyPointInfo", compKeyPointVo);
                    return map;
                }
            }
        }
        //找不到阶段抛出异常
        throw new AppException(ErrorCode.FIND_STAGE_STATUS_CURRENT_TIME_FAIL);
    }

    /**
     * 根据时间节点确定当前stageId
     *
     * @param compId
     * @return
     */
    public Integer getStageIdByTime(int compId) {
        if(competitionMapper.selectCount(new QueryWrapper<Competition>().eq("comp_id",compId))<1){
            throw new AppException(ErrorCode.COMPETITION_LACK);
        }
        List<CompetitionStage> stages = competitionStageService.getStageByCompId(compId);
        for (CompetitionStage stage : stages) {
            List<CompetitionStageStatus> compStageStatusList = competitionStageStatusService.getCompStageStatus(stage.getStageId());
            Date date = new Date();

            for (CompetitionStageStatus competitionStageStatus : compStageStatusList) {
                if (CheckUtil.checkStageStatusByTime(stage, competitionStageStatus, date, stages.size())){
                    //初赛提交开始前为提交状态,在开始和结束时间内为该状态,复赛当前时间晚于公示结束时间，为公示阶段
                    return stage.getStageId();
                }
            }
        }
        //找不到阶段抛出异常
        throw new AppException(ErrorCode.FIND_STAGE_STATUS_CURRENT_TIME_FAIL);
    }

    /**
     * 创建新的比赛详细信息
     *
     * @param competitionDetailDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Map addCompDetail(CompetitionDetailDto competitionDetailDto) {
        // 首先加入竞赛基础信息并获取竞赛Id,根据时间重置竞赛状态
        CompetitionDto competitionDto = competitionDetailDto.getCompetitionDto();
        competitionDetailDto.getCompetitionStageDetailDtoList().forEach(competitionStageDetailDto ->{
            List<CompetitionStageStatusDto> competitionStageStatusDtoList = competitionStageDetailDto.getCompetitionStageStatusDtoList();
            Date date = new Date();
            for (CompetitionStageStatusDto competitionStageStatusDto : competitionStageStatusDtoList) {
                if (competitionStageDetailDto.getCompetitionStageDto().getStageOrder() == 1 && competitionStageStatusDto.getStatusOrder() == 1 && date.before(competitionStageStatusDto.getStatusStartTime())) {
                    competitionDto.setCompStatus(StatusConstant.COMPETITION_STATUS_NOT_COMMENCED.getCode());
                } else if (competitionStageDetailDto.getCompetitionStageDto().getStageOrder() == competitionDetailDto.getCompetitionStageDetailDtoList().size() && competitionStageStatusDto.getStatusOrder() == competitionStageStatusDtoList.size() && date.after(competitionStageStatusDto.getStatusEndTime())) {
                    competitionDto.setCompStatus(StatusConstant.COMPETITION_STATUS_COMPELETED.getCode());
                } else {
                    competitionDto.setCompStatus(StatusConstant.COMPETITION_STATUS_ONGOING.getCode());;
                }
            }
        });
        int compId = this.addCompInfo(competitionDetailDto.getCompetitionDto());
        List<Integer> stageIdList = new ArrayList<>();
        //加入每个竞赛阶段信息
        competitionDetailDto.getCompetitionStageDetailDtoList().forEach(competitionStageDetailDto -> {
            int stageId = competitionStageService.addCompStage(compId, competitionStageDetailDto.getCompetitionStageDto());
            stageIdList.add(stageId);
            competitionKeyPointService.addCompKeyPointByList(compId, stageId, competitionStageDetailDto.getCompetitionKeyPointDtoList());
//            academyCompetitionService.addAcademyCompByList(compId, stageId, competitionStageDetailDto.getAcademyCompetitionDtoList());
            competitionStageStatusService.addCompStageStatusByList(stageId, competitionStageDetailDto.getCompetitionStageStatusDtoList());
            competitionStageAwardService.addCompStageAwardByList(stageId, competitionStageDetailDto.getCompetitionStageAwardDtoList());
        });
        return Map.of("compId", compId, "stageIds", stageIdList);
    }


    /**
     * 根据比赛详细信息更新比赛信息
     *
     * @param competitionDetailVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String updateCompById(CompetitionDetailVo competitionDetailVo) {
        int compId = competitionDetailVo.getCompetitionVo().getCompId();
        if(competitionMapper.selectCount(new QueryWrapper<Competition>().eq("comp_id",compId))<1){
            throw new AppException(ErrorCode.COMPETITION_LACK);
        }
        List<Integer> stageIdList = competitionDetailVo.getCompetitionStageDetailList()
                .stream().map(CompetitionStageDetailVo::getCompetitionStageVo).collect(Collectors.toList())
                .stream().map(CompetitionStageVo::getStageId).collect(Collectors.toList());

        Competition competition = new Competition();
        BeanUtils.copyProperties(competitionDetailVo.getCompetitionVo(), competition);
        //覆写不可以改变的属性
        Competition competitionById = this.getCompetitionById(compId);
        competition.setTeamNum(competitionById.getTeamNum());
        competition.setCompJudgeWay(competitionById.getCompJudgeWay());
        competition.setCompSchoolRecAmt(competitionById.getCompSchoolRecAmt());
        competition.setCompStatus(competitionById.getCompStatus());
        competitionMapper.update(competition, new QueryWrapper<Competition>().eq("comp_id", compId));
        List<Integer> existStageIds = competitionStageService.getStageIdByCompId(compId);
        int idx = 0;
        for (int stageId : stageIdList) {
            CompetitionStageDetailVo competitionStageDetail = competitionDetailVo.getCompetitionStageDetailList().get(idx);
            Integer curStageId = null;
            //如果存在更新，否则增加stage，禁止删除stage，牵扯面太广
            if(existStageIds.contains(stageId)){
                competitionStageService.updateCompStageById(compId, stageId, competitionStageDetail.getCompetitionStageVo());
            }else {
//                competitionStageService.delCompStage(stageId);
                CompetitionStageDto competitionStageDto = new CompetitionStageDto();
                BeanUtils.copyProperties(competitionStageDetail.getCompetitionStageVo(), competitionStageDto);
                curStageId = competitionStageService.addCompStage(compId, competitionStageDto);
            }

            curStageId = (curStageId == null ? stageId: curStageId);
            //必须先删除在插入，如果是更新会因为没有主键而重复在最后一个
            competitionStageAwardService.delCompStageAward(curStageId);
            for (CompetitionStageAwardVo competitionStageAwardVo : competitionStageDetail.getCompetitionStageAwardVoList()) {
                CompetitionStageAwardDto competitionStageAwardDto = new CompetitionStageAwardDto();
                BeanUtils.copyProperties(competitionStageAwardVo, competitionStageAwardDto);
                competitionStageAwardService.addCompStageAward(curStageId, competitionStageAwardDto);
            }

            competitionKeyPointService.delCompKeyPointById(curStageId);
            for (CompetitionKeyPointVo competitionKeyPoint : competitionStageDetail.getCompetitionKeyPointVoList()) {
                CompetitionKeyPointDto competitionKeyPointDto = new CompetitionKeyPointDto();
                BeanUtils.copyProperties(competitionKeyPoint, competitionKeyPointDto);
                competitionKeyPointService.addCompKeyPoint(compId, curStageId, competitionKeyPointDto);
            }

            //校验StageStatus的上下阶段承接关系
            Set<Date> dates = new HashSet<>();
            competitionStageDetail.getCompetitionStageStatusVoList().forEach(competitionStageStatusDto -> {
                dates.add(competitionStageStatusDto.getStatusStartTime());
                dates.add(competitionStageStatusDto.getStatusEndTime());
            });
            if (dates.size() != 4) {
                throw new AppException(ErrorCode.STAGE_STATUS_TIME);
            }

            competitionStageStatusService.delCompStageStatusByStageId(curStageId);
            for (CompetitionStageStatusVo competitionStageStatusVo : competitionStageDetail.getCompetitionStageStatusVoList()) {
                CompetitionStageStatusDto competitionStageStatusDto = new CompetitionStageStatusDto();
                BeanUtils.copyProperties(competitionStageStatusVo, competitionStageStatusDto);
                competitionStageStatusService.addCompStageStatus(curStageId, competitionStageStatusDto);
            }

            idx += 1;
        }

        return "更新信息成功";
    }


    /**
     * 根据比赛类型分页获取比赛粗略信息
     *
     * @param compType
     * @param compStatus
     * @param compYear
     * @param offset
     * @param pageSize
     * @return
     */
    public Map<String, Object> getCompetitionRoughPageable(Integer compType, Integer compStatus, Integer compYear, int offset, int pageSize) {
        List<CompetitionRoughVo> compRoughVos = new ArrayList<>();
        List<Competition> competitionList = competitionMapper.getCompetitionPageable(compType, compStatus, compYear, offset, pageSize);
        competitionList.forEach(competition -> {
            Integer compId = competition.getCompId();
            //根据时间节点确定当前stage等信息
            Map<String, Object> stageInfoByTime = this.getStageInfoByTime(compId);
            CompetitionRoughVo competitionRoughVo = new CompetitionRoughVo();
            BeanUtils.copyProperties(competition, competitionRoughVo);
            competitionRoughVo.setKeyPoints((List<CompetitionKeyPointVo>) stageInfoByTime.get("compKeyPointInfo"));
            compRoughVos.add(competitionRoughVo);
        });
        int recordNum = competitionMapper.getPageNum(compType, compStatus, compYear);
        return Map.of("data", compRoughVos, "total", recordNum);
    }

    /**
     * 根据compId和stageId获取竞赛粗略信息
     *
     * @param compId
     * @param stageId
     * @return
     */
    public CompetitionStageRoughInfoVo getCompetitionRoughByCompIdAndStageId(int compId, int stageId){
        Competition competition = this.getCompetitionById(compId);
        CompetitionStageRoughInfoVo competitionStageRoughInfoVo = new CompetitionStageRoughInfoVo();
        BeanUtils.copyProperties(competition, competitionStageRoughInfoVo);
        competitionStageRoughInfoVo.setStageId(stageId);
        competitionStageRoughInfoVo.setCompName(StatusConvertUtil.convertCompName(competition.getCompType()));
        competitionStageRoughInfoVo.setCurStageName(competitionStageService.getStageVoById(stageId).getStageName());
        competitionStageRoughInfoVo.setCompStatusName(StatusConvertUtil.convertCompStatus(competition.getCompStatus()));
        competitionStageRoughInfoVo.setCompKeyPointInfo(competitionKeyPointService.getCompKeyPointVo(compId, stageId));
        return competitionStageRoughInfoVo;
    }

    /**
     * 根据比赛类型分页获取此用户有权限的比赛粗略信息
     *
     * @param userId
     * @param compType
     * @param compStatus
     * @param compYear
     * @return
     */
    public List<CompetitionStuRoughVo> getUserCompetitionRough(int userId, Integer compType, Integer compStatus, Integer compYear) {
        //获取我参加过的所有项目Id
        Set<Integer> projectIdByMemberId = projectMemberService.getProjectIdByMemberIdConditional(userId, compType, compStatus, compYear);
        System.out.println("projectIdByMemberId:" + projectIdByMemberId.toString());
        List<CompetitionStuRoughVo> competitionStuRoughVoList = new ArrayList<>();
        //获得所有项目的stu粗略信息
        for (Integer projectId : projectIdByMemberId) {
            System.out.println("nowId:" + projectId);
            CompetitionStuRoughVo competitionStuRoughVo = new CompetitionStuRoughVo();
            int compId = (int) projectService.getCompIdByProjectId(projectId);
            System.out.println("nowCompId:" + compId);
            //设置项目相关字段
            ProjectDetailVo projectDetail = projectService.getProjectDetailById(projectId);
            //如果项目已经删除则跳过
            if(projectDetail == null){ continue; }
            System.out.println("projectDetail:" + projectDetail.toString());
            BeanUtils.copyProperties(projectDetail, competitionStuRoughVo);
            //项目状态(1:待提交、2:已提交、3:已退回、4:已完结) 学生视角
            competitionStuRoughVo.setProjectStudentStatusId(projectDetail.getProjectStudentStatus());
            competitionStuRoughVo.setProjectStudentStatusName(StatusConvertUtil.convertProjectStuStatus(projectDetail.getProjectStudentStatus()));
            //设置项目负责人姓名
            competitionStuRoughVo.setProjectLeaderName(studentInfoService.getNameById(userId));

            //设置竞赛相关字段
            Competition competition = competitionMapper.selectById(compId);
            BeanUtils.copyProperties(competition, competitionStuRoughVo);

            Map<String, Object> stageInfoByTime = this.getStageInfoByTime(compId);
            CompetitionStageStatus competitionStageStatus = (CompetitionStageStatus) stageInfoByTime.get("competitionStageStatus");
            CompetitionStage competitionStage = (CompetitionStage) stageInfoByTime.get("competitionStage");
//            List<CompetitionKeyPointVo> compKeyPoints = (List<CompetitionKeyPointVo>) stageInfoByTime.get("compKeyPointInfo");

            //设置当前所处阶段
            competitionStuRoughVo.setCurStageName(competitionStageService.getStageVoById(competitionStage.getStageId()).getStageName());
            //设置项目名称
            competitionStuRoughVo.setCompName(StatusConvertUtil.convertCompName(competitionStuRoughVo.getCompType()));
            //赛事状态（1:NotCommenced、2:Ongoing、3:Completed）
            competitionStuRoughVo.setProjectStudentStatusName(StatusConvertUtil.convertCompStatus(competition.getCompStatus()));
            //设置stageStatus相关内容
            BeanUtils.copyProperties(competitionStageStatus, competitionStuRoughVo);

            competitionStuRoughVoList.add(competitionStuRoughVo);
        }
        //自定义排序，退回修改——未提交——已提交——已完结
        Collections.sort(competitionStuRoughVoList, new Comparator<CompetitionStuRoughVo>() {
            @Override
            public int compare(CompetitionStuRoughVo o1, CompetitionStuRoughVo o2) {
                if (o1.getProjectStudentStatusId() == StatusConstant.PROJECT_STUDENT_STATUS_RETURN.getCode()) {
                    return -1;
                }else if(o2.getProjectStudentStatusId() == StatusConstant.PROJECT_STUDENT_STATUS_RETURN.getCode()) {
                    return 1;
                }else{
                    return o1.getProjectStudentStatusId()-o2.getProjectStudentStatusId();
                }
            }
        });
        return competitionStuRoughVoList;
    }


    /**
     * 创建新的比赛单体信息
     *
     * @param competitionDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int addCompInfo(CompetitionDto competitionDto) {
        Competition comp = new Competition();
        BeanUtils.copyProperties(competitionDto, comp);
        competitionMapper.insert(comp);
        return comp.getCompId();
    }


    /**
     * 根据比赛类型和届数获取比赛Id
     *
     * @param compType
     * @param compTh
     * @return
     */
    public int getCompId(int compType, int compTh) {
        return competitionMapper.selectOne(new QueryWrapper<Competition>().eq("comp_type", compType).eq("comp_th", compTh)).getCompId();
    }


    /**
     * 赛事进入下一个状态
     *
     * @param compId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int enterNextStatus(int compId) {
        if(competitionMapper.selectCount(new QueryWrapper<Competition>().eq("comp_id",compId))<1){
            throw new AppException(ErrorCode.COMPETITION_LACK);
        }
        int curStatus = competitionMapper.selectById(compId).getCompStatus();
        return competitionMapper.setCompStatus(curStatus < 3 ? curStatus + 1 : 3, compId);
    }


    /**
     * 获取当前赛事最新届数
     *
     * @param compType
     * @return
     */
    public int getNewTh(int compType) {
        Competition competition = competitionMapper.selectOne(new QueryWrapper<Competition>().eq("comp_Type", compType).orderByDesc("comp_th").last("limit 1"));
        return competition == null ? 1 : competition.getCompTh() + 1;
    }

    /**
     * 获取当前赛事除了本赛事的最新届数（用于修改项目）
     *
     * @param compType
     * @return
     */
    public int getNewThExceptThis(int compType, int compId) {
        Competition competition = competitionMapper.selectOne(new QueryWrapper<Competition>().eq("comp_Type", compType).ne("comp_id",compId).orderByDesc("comp_th").last("limit 1"));
        return competition == null ? 1 : competition.getCompTh() + 1;
    }


    /**
     * 获取当前未完结的赛事 List
     *
     * @return
     */
    public List<Map<String, Object>> getOngoingComp() {
        List<Map<String, Object>> maps = competitionMapper.selectMaps(new QueryWrapper<Competition>().select("comp_id", "comp_year", "comp_type", "comp_th", "comp_status").ne("comp_status", StatusConstant.COMPETITION_STATUS_COMPELETED.getCode()).orderByDesc("comp_type","comp_year","comp_th"));

        maps.forEach(map -> {
            //设置项目名称
            map.put("compName", StatusConvertUtil.convertCompName((int) map.get("comp_type")));

            //设置项目状态
            map.put("compStatusName", StatusConvertUtil.convertCompStatus((int) map.get("comp_status")));

            int compId = (int) map.get("comp_id");

            Map<String, Object> stageInfoByTime = this.getStageInfoByTime(compId);
            map.put("stageId", ((CompetitionStage) stageInfoByTime.get("competitionStage")).getStageId());
            map.put("curStageName", ((CompetitionStage) stageInfoByTime.get("competitionStage")).getStageName());
            map.put("compKeyPointInfo", (List<CompetitionKeyPointVo>) stageInfoByTime.get("compKeyPointInfo"));

//            List<CompetitionStage> stages = competitionStageService.getStageByCompId(compId);
//            stages.forEach(stage->{
//                List<CompetitionStageStatus> compStageStatusList = competitionStageStatusService.getCompStageStatus(compId, stage.getStageId());
//                Date date = new Date();
//                for (CompetitionStageStatus competitionStageStatus : compStageStatusList) {
//                    if((date.before(competitionStageStatus.getStatusStartTime()) && competitionStageStatus.getStatusOrder()==1) ||
//                            (date.after(competitionStageStatus.getStatusStartTime()) && date.before(competitionStageStatus.getStatusEndTime())) ||
//                            date.after(competitionStageStatus.getStatusEndTime()) && competitionStageStatus.getStatusOrder()==compStageStatusList.size()){
//                        //提交开始前为提交状态,在开始和结束时间内为该状态,当前时间晚于公示结束时间，为公示阶段
//                        map.put("stageId",competitionStageStatus.getStageId());
//                        map.put("curStageName",stage.getStageName());
//                        List<CompetitionKeyPointVo> compKeyPointVo = competitionKeyPointService.getCompKeyPointVo(compId, competitionStageStatus.getStageId());
//                        map.put("compKeyPointInfo",compKeyPointVo);
//                        break;
//                    }
//                }
//            });
        });
        return maps;
    }

    /**
     * 创建项目时需要获取的竞赛相关信息
     *
     * @param compId
     * @return
     */
    public Map<String, Object> getCompInfoWhenCreateProject(int compId) {
        Map<String, Object> map = new HashMap<>();
        List<CompetitionStage> stages = competitionStageService.getStageByCompId(compId);
        Competition competition = competitionMapper.selectById(compId);
        map.put("compType", competition.getCompType());
        map.put("compTh", competition.getCompTh());
        map.put("compYear", competition.getCompYear());
        //设置项目名称
        map.put("compName", StatusConvertUtil.convertCompName(competition.getCompType()));

        //设置stage相关信息以及keypoints
        map.put("stageInfoByTime", this.getStageInfoByTime(compId));
        //设置校团委可推荐数量
        map.put("compSchoolRecAmt", this.getCompetitionById(compId).getCompSchoolRecAmt());
        //设置团队上限人数
        map.put("teamNum", competition.getTeamNum());
        return map;
    }

    /**
     * 获取当前最新赛事的状态
     *
     * @return
     */
    public List<Map<String, Object>> getCompStatusInfo() {
        List<Map<String, Object>> maps = new ArrayList<>();
        for (int compType = 1; compType <= 4; compType++) {
            List<Map<String, Object>> maps1 = competitionMapper.selectMaps(new QueryWrapper<Competition>().select("comp_id", "comp_year", "comp_type", "comp_th", "comp_status").eq("comp_type", compType).orderByDesc("comp_th").last("limit 1"));
            if (maps1.size() < 1) {
                continue;
            }
            Map<String, Object> map = maps1.get(0);
            //设置项目名称
            map.put("compName", StatusConvertUtil.convertCompName(compType));
            //设置项目状态
            map.put("compStatusName", StatusConvertUtil.convertCompStatus((int) map.get("comp_status")));

            int compId = (int) map.get("comp_id");

            Map<String, Object> newMap = this.getCompStatusInfoByCompId(compId, map);

            maps.add(newMap);
        }


        return maps;
    }

    /**
     * 根据赛事Id返回最新赛事信息
     *
     * @return
     */
    public Map<String, Object> getCompStatusInfoByCompId(int compId, Map map){
        List<CompetitionStage> stages = competitionStageService.getStageByCompId(compId);

        for (CompetitionStage stage : stages) {
            List<CompetitionStageStatus> compStageStatusList = competitionStageStatusService.getCompStageStatus(stage.getStageId());
            Date date = new Date();
            for (CompetitionStageStatus competitionStageStatus : compStageStatusList) {
                if (date.before(competitionStageStatus.getStatusStartTime()) && stage.getStageOrder() == StatusConstant.COMPETITION_STAGE_PRELIMINARY.getCode() && competitionStageStatus.getStatusOrder() == StatusConstant.COMPETITION_STAGE_STATUS_ORDER_SUBMIT.getCode()) {
                    map.put("compStatusName", "NotCommenced");
                } else if (date.after(competitionStageStatus.getStatusEndTime()) && stage.getStageOrder() == stages.size() && competitionStageStatus.getStatusOrder() == compStageStatusList.size()) {
                    map.put("compStatusName", "Completed");
                } else {
                    map.put("compStatusName", "Ongoing");
                }

                if ((date.before(competitionStageStatus.getStatusStartTime()) && competitionStageStatus.getStatusOrder() == StatusConstant.COMPETITION_STAGE_STATUS_ORDER_SUBMIT.getCode()) ||
                        (date.after(competitionStageStatus.getStatusStartTime()) && date.before(competitionStageStatus.getStatusEndTime())) ||
                        (stage.getStageOrder() == stages.size() && date.after(competitionStageStatus.getStatusEndTime()) && competitionStageStatus.getStatusOrder() == compStageStatusList.size())) {
                    //提交开始前为提交状态,在开始和结束时间内为该状态,当前时间晚于公示结束时间，为公示阶段
                    map.put("stageId", competitionStageStatus.getStageId());
                    map.put("curStageName", stage.getStageName());
                    map.put("stageOrder", stage.getStageOrder());
                    CompetitionStageStatusVo competitionStageStatusVo = new CompetitionStageStatusVo();
                    BeanUtils.copyProperties(competitionStageStatus, competitionStageStatusVo);
                    map.put("stageStatusVo", competitionStageStatusVo);
                    // 阶段状态按照order排序，当匹配到就切换利于决定初赛 复赛 交接的空白期是复赛未开始
                    return map;
                }
            }
        }
        //找不到阶段抛出异常
        throw new AppException(ErrorCode.FIND_STAGE_STATUS_CURRENT_TIME_FAIL);
    }

    /**
     * 根据比赛Id获取比赛全量信息
     *
     * @param compId
     * @return
     */
    public CompetitionDetailVo getCompetitionInfo(int compId) {
        CompetitionDetailVo competitionDetailVo = new CompetitionDetailVo();
        CompetitionVo compVo = new CompetitionVo();
        BeanUtils.copyProperties(competitionMapper.selectById(compId), compVo);

        compVo.setCompName(StatusConvertUtil.convertCompName(compVo.getCompType()));
        //设置项目名称
        competitionDetailVo.setCompetitionVo(compVo);

        List<Integer> stageList = competitionStageService.getStageIdByCompId(compId);
        List<CompetitionStageDetailVo> competitionStageDetailVos = new ArrayList<CompetitionStageDetailVo>();

        stageList.forEach(
                stageId -> {
                    CompetitionStageDetailVo competitionStageDetailVo = new CompetitionStageDetailVo();

                    competitionStageDetailVo.setCompetitionStageVo(competitionStageService.getStageVoById((int) stageId));
                    competitionStageDetailVo.setCompetitionStageAwardVoList(competitionStageAwardService.getCompStageAwardListById((int) stageId));
                    competitionStageDetailVo.setCompetitionKeyPointVoList(competitionKeyPointService.getCompKeyPointVo(compId, (int) stageId));
                    competitionStageDetailVo.setCompetitionStageStatusVoList(competitionStageStatusService.getCompStageStatusById((int) stageId));

                    competitionStageDetailVos.add(competitionStageDetailVo);
                }
        );
        competitionDetailVo.setCompetitionStageDetailList(competitionStageDetailVos);
        return competitionDetailVo;
    }

    /**
     * 获得团队上限人数
     *
     * @param compId
     * @return
     */
    public Object getMemberLimit(int compId) {
        List<Object> lo = competitionMapper.selectObjs(new QueryWrapper<Competition>().eq("comp_id", compId).select("team_num"));
        return lo.size() > 0 ? lo.get(0) : 0;
    }

    /**
     * 删除竞赛
     * TODO 管理员删除后给项目负责人发送站内信提醒逻辑
     *
     * @param compId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int deleteComp(int compId) {
        if(competitionMapper.selectCount(new QueryWrapper<Competition>().eq("comp_id",compId))<1){
            throw new AppException(ErrorCode.COMPETITION_LACK);
        }
        //删除比赛的评审信息
        judgeProjectDistributionService.deleteJudgeProjectDistributionByCompId(compId);

        List<Integer> stageIds = competitionStageService.getStageIdByCompId(compId);
        //删除项目相关信息
        stageIds.forEach(stageId -> {
            projectScoreService.deleteProjectScoreByStageId(stageId);
            projectReturnLogService.deleteReturnLogByStageId(stageId);
        });


        projectService.getProjectIdByCompId(compId).forEach(projectId -> {
            //删除指导老师
            projectTeacherService.deleteProjectTeacher((int) projectId, null);
            //删除成员
            projectMemberService.deleteProjectMember((int) projectId, null);
            //删除成员申请信息
            projectMemberApplyService.deleteProjectMemberApply((int) projectId);
            //删除项目
            projectService.deleteProjectById((int) projectId);
        });
        //删除竞赛相关信息
        stageIds.forEach(stageId -> {
            //1、删除stageAward信息
            competitionStageAwardService.delCompStageAward(stageId);
            //2、删除stageStatus信息
            competitionStageStatusService.delCompStageStatusByStageId(stageId);
            //3、删除stageKeyPoint信息
            competitionKeyPointService.delCompKeyPointById(stageId);
            //4、删除stage信息
            competitionStageService.delCompStage(stageId);
        });
        //6、删除比赛对应的竞赛
        return competitionMapper.deleteById(compId);
    }


    /**
     * 获取正在进行中的比赛Type
     *
     * @return
     */
    public Set<Object> getOngoingCompType(){
        List<Object> objects = competitionMapper.selectObjs(new QueryWrapper<Competition>().ne("comp_status", StatusConstant.COMPETITION_STATUS_COMPELETED.getCode()).select("comp_type"));
        return new HashSet<Object>(objects);
    }

    /**
     * 根据Id获取比赛信息
     *
     * @param compId
     * @return
     */
    public Competition getCompetitionById(int compId){
        return competitionMapper.selectById(compId);
    }

    /**
     * 获得当前正在进行中的项目Id
     *
     * @return
     */
    public List<Object> getOngoingCompId(){
        return competitionMapper.selectObjs(new QueryWrapper<Competition>().select("comp_id").ne("comp_status", StatusConstant.COMPETITION_STATUS_COMPELETED.getCode()));
    }

    /**
     * 更新项目信息
     *
     * @param competition
     * @return
     */
    public int updateCompById(Competition competition){
        if(competitionMapper.selectCount(new QueryWrapper<Competition>().eq("comp_id",competition.getCompId()))<1){
            throw new AppException(ErrorCode.COMPETITION_LACK);
        }
        return competitionMapper.updateById(competition);
    }

    /**
     * 获得推荐项目审核粗略信息
     *
     * @return
     */
    public SchoolRecInfoVo getSchoolRecInfoVo(int compId, int stageId){
        SchoolRecInfoVo schoolRecInfoVo = new SchoolRecInfoVo();
        schoolRecInfoVo.setCompSchoolRecAmt(competitionMapper.selectById(compId).getCompSchoolRecAmt());
        schoolRecInfoVo.setAlreadyRecNum(projectService.getSchoolAlreadyRecNum(stageId));
        schoolRecInfoVo.setEnrollNum(projectService.getSchoolEnrollNum(stageId));
        return schoolRecInfoVo;
    }

    /**
     * 获取竞赛评审标准
     *
     * @param compId
     * @return
     */
    public String getStandardByCompId(int compId){
        List<Object> objects = competitionMapper.selectObjs(new QueryWrapper<Competition>().eq("comp_id", compId).select("comp_judge_standard"));
        return objects.get(0).toString();
    }

    /**
     * 根据比赛类型获取已结束的比赛年份和对应的阶段ID、阶段名
     *
     * @param compType
     * @return
     */
    public List<CompeletedCompInfoVo> getCompeletedCompInfo(int compType){
        List<Map<String, Object>> maps = competitionMapper.selectMaps(new QueryWrapper<Competition>().eq("comp_type", compType).select("comp_id", "comp_year"));
        return competitionStageService.getCompeletedStageInfo(maps);
    }
}